home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / payloads / external / inlineegg.py < prev    next >
Text File  |  2006-06-30  |  63KB  |  2,101 lines

  1. #--
  2. # Copyright (c) 2002,2003 Core Security Technologies, Core SDI Inc.
  3. # All rights reserved.
  4. #
  5. #    Unless you have express writen permission from the Copyright Holder, any
  6. # use of or distribution of this software or portions of it, including, but not
  7. # limited to, reimplementations, modifications and derived work of it, in
  8. # either source code or any other form, as well as any other software using or
  9. # referencing it in any way, may NOT be sold for commercial gain, must be
  10. # covered by this very same license, and must retain this copyright notice and
  11. # this license.
  12. #    Neither the name of the Copyright Holder nor the names of its contributors
  13. # may be used to endorse or promote products derived from this software
  14. # without specific prior written permission.
  15. #
  16. # THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE
  17. # LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
  18. # OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
  19. # EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
  21. # ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU.
  22. # SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
  23. # SERVICING, REPAIR OR CORRECTION.
  24. #
  25. # IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
  26. # ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
  27. # THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
  28. # GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
  29. # OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
  30. # DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR
  31. # A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
  32. # HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  33. #
  34. # gera [at corest.com]
  35. #--
  36. # $Id: inlineegg.py,v 1.3 2004/02/05 07:57:30 hdm Exp $
  37.  
  38. import struct
  39. import types
  40.  
  41. class Variable:
  42.     def __init__(self, offset, size = None):
  43.         self.offset = offset
  44.         self.size   = size
  45.  
  46.     def value(self,delta = 0):
  47.         return 'var%d' % (self.offset+delta)
  48.  
  49.     def addr(self,delta = 0):
  50.         return 'ptr%d' % (self.offset+delta)
  51.  
  52.     def __add__(self,delta):
  53.         return self.__class__(self.offset-delta,self.size and self.size-delta)
  54.  
  55.     def __sub__(self,delta):
  56.         return self + -delta
  57.  
  58.     def startswith(self,string):
  59.         return string == 'var'
  60.  
  61. class Microprocessor:
  62.     pass
  63.  
  64. class Microx86(Microprocessor):
  65.     # zero causes:
  66.     #   push    0, push 0x00001234, push 0x00123456, push 0x12000034
  67.     #   mov     dx, 0x400
  68.     #   sub     esp, 0x400
  69.     #   mov     esi, [esp+0x41c]
  70.     #   mov     ebx, [esp]
  71.     #   cmp     eax,0
  72.     def __init__(self):
  73.         self._registers = ['eax','ecx','edx','ebx','esp','ebp','esi','edi']
  74.         self.opcodes = {
  75.             '': {
  76.             # stack
  77.                 'pushb':'\x6a%c',
  78.                 'pushl':'\x68%s',
  79.                 'pushVarb':'\xff\x74\x24%c',
  80.                 'pushVarl':'\xff\xb4\x24%s',
  81.                 'pushVarPtrb':'\x54\x83\x2c\x24%c',    # push esp; sub $ptr, (%esp)
  82.                 'pushVarPtrl':'\x54\x81\x2c\x24%s',    # push esp; sub $ptr, (%esp)
  83.                 'cmpbVarb':'\x83\x7c\x24%c%c',         # off, val : cmpl $val, off(%esp) 
  84.                 'cmpbVarl':'\x83\xbc\x24%s%c',         # off, val : cmpl $val, off(%esp) 
  85.                 'cmplVarb':'\x81\x7c\x24%c%s',         # off, val : cmpl $val, off(%esp) 
  86.                 'cmplVarl':'\x81\xbc\x24%s%s',         # off, val : cmpl $val, off(%esp) 
  87.                 'callVarb':'\xff\x54\x24%c',
  88.                 'callVarl':'\xff\x94\x24%s',
  89.                 'incVarb':'\xff\x44\x24%c',
  90.                 'incVarl':'\xff\x84\x24%s',
  91.                 'decVarb':'\xff\x4c\x24%c',
  92.                 'decVarl':'\xff\x8c\x24%s',
  93.  
  94.  
  95.             # jumps
  96.                 'jmpb':'\xeb%(b)s',
  97.                 'jmpl':'\xe9%(l)s',
  98.                 'jmpb=':'\x74%(b)s',
  99.                 'jmpb!=':'\x75%(b)s',
  100.                 '!=':'!=',                             # the oposite condition is used on ifs
  101.                 '!!=':'=',
  102.                 'jmpb<':'\x72%(b)s',
  103.                 'jmpb>=':'\x73%(b)s',
  104.                 '!<':'>=',
  105.                 '!>=':'<',
  106.             },
  107.             'eax': {
  108.                 'value':None,
  109.                 'movb':'\xb0%(b)s',
  110.                 'movw':'\x66\xb8%(w)s',
  111.                 'movl':'\xb8%(l)s',
  112.                 'cmpb':'\x83\xf8%(b)s',
  113.                 'cmpl':'\x3d%(l)s',
  114.                 'zero':'\x31\xc0',
  115.                 'moveax':'',
  116.                 'movebx':'\x89\xd8',
  117.                 'movecx':'\x89\xc8',
  118.                 'movedx':'\x89\xd0',
  119.                 'movesi':'\x89\xf0',
  120.                 'movedi':'\x89\xf8',
  121.                 'movebp':'\x89\xe8',
  122.                 'movesp':'\x89\xe0',
  123.                 'cmpeax':'\x39\xc0',
  124.                 'cmpebx':'\x39\xc3',
  125.                 'cmpecx':'\x39\xc1',
  126.                 'cmpedx':'\x39\xc2',
  127.                 'cmpesi':'\x39\xc6',
  128.                 'cmpedi':'\x39\xc7',
  129.                 'cmpebp':'\x39\xc5',
  130.                 'cmpesp':'\x39\xc4',
  131.                 'movVarb':'\x8b\x44\x24%(b)s',
  132.                 'movVarl':'\x8b\x84\x24%(l)s',
  133.                 'movVarPtrb':'\x8d\x44\x24%(b)s',
  134.                 'movVarPtrl':'\x8d\x84\x24%(l)s',
  135.                 'subb':None,
  136.                 'subl':None,
  137.                 'subVarb':None,
  138.                 'subVarl':None,
  139.             },
  140.             'ebx': {
  141.                 'value':None,
  142.                 'movb':'\xb3%(b)s',
  143.                 'movw':'\x66\xbb%(w)s',
  144.                 'movl':'\xbb%(l)s',
  145.                 'cmpb':'\x83\xfb%(b)s',
  146.                 'cmpl':'\x81\xfb%(l)s',
  147.                 'zero':'\x31\xdb',
  148.                 'moveax':'\x89\xc3',
  149.                 'movebx':'',
  150.                 'movecx':'\x89\xcb',
  151.                 'movedx':'\x89\xd3',
  152.                 'movesi':'\x89\xf3',
  153.                 'movedi':'\x89\xfb',
  154.                 'movebp':'\x89\xeb',
  155.                 'movesp':'\x89\xe3',
  156.                 'cmpeax':'\x39\xd8',
  157.                 'cmpebx':'\x39\xdb',
  158.                 'cmpecx':'\x39\xd9',
  159.                 'cmpedx':'\x39\xda',
  160.                 'cmpesi':'\x39\xde',
  161.                 'cmpedi':'\x39\xdf',
  162.                 'cmpebp':'\x39\xdd',
  163.                 'cmpesp':'\x39\xdc',
  164.                 'movVarb':'\x8b\x5c\x24%(b)s',
  165.                 'movVarl':'\x8b\x9c\x24%(l)s',
  166.                 'movVarPtrb':'\x8d\x5c\x24%(b)s',
  167.                 'movVarPtrl':'\x8d\x9c\x24%(l)s',
  168.                 'subb':None,
  169.                 'subl':None,
  170.                 'subVarb':None,
  171.                 'subVarl':None,
  172.             },
  173.             'ecx': {
  174.                 'value':None,
  175.                 'movb':'\xb1%(b)s',
  176.                 'movw':'\x66\xb9%(w)s',
  177.                 'movl':'\xb9%(l)s',
  178.                 'cmpb':'\x83\xf9%(b)s',
  179.                 'cmpl':'\x81\xf9%(l)s',
  180.                 'zero':'\x31\xc9',
  181.                 'moveax':'\x89\xc1',
  182.                 'movebx':'\x89\xd9',
  183.                 'movecx':'',
  184.                 'movedx':'\x89\xd1',
  185.                 'movesi':'\x89\xf1',
  186.                 'movedi':'\x89\xf9',
  187.                 'movebp':'\x89\xe9',
  188.                 'movesp':'\x89\xe1',
  189.                 'cmpeax':'\x39\xc8',
  190.                 'cmpebx':'\x39\xcb',
  191.                 'cmpecx':'\x39\xc9',
  192.                 'cmpedx':'\x39\xca',
  193.                 'cmpesi':'\x39\xce',
  194.                 'cmpedi':'\x39\xcf',
  195.                 'cmpebp':'\x39\xcd',
  196.                 'cmpesp':'\x39\xcc',
  197.                 'movVarb':'\x8b\x4c\x24%(b)s',
  198.                 'movVarl':'\x8b\x8c\x24%(l)s',
  199.                 'movVarPtrb':'\x8d\x4c\x24%(b)s',
  200.                 'movVarPtrl':'\x8d\x8c\x24%(l)s',
  201.                 'subb':None,
  202.                 'subl':None,
  203.                 'subVarb':None,
  204.                 'subVarl':None,
  205.             },
  206.             'edx': {
  207.                 'value':None,
  208.                 'movb':'\xb2%(b)s',
  209.                 'movw':'\x66\xba%(w)s',
  210.                 'movl':'\xba%(l)s',
  211.                 'cmpb':'\x83\xfa%(b)s',
  212.                 'cmpl':'\x81\xfa%(l)s',
  213.                 'zero':'\x31\xd2',
  214.                 'moveax':'\x89\xc2',
  215.                 'movebx':'\x89\xda',
  216.                 'movecx':'\x89\xca',
  217.                 'movedx':'',
  218.                 'movesi':'\x89\xf2',
  219.                 'movedi':'\x89\xfa',
  220.                 'movebp':'\x89\xea',
  221.                 'movesp':'\x89\xe2',
  222.                 'cmpeax':'\x39\xd0',
  223.                 'cmpebx':'\x39\xd3',
  224.                 'cmpecx':'\x39\xd1',
  225.                 'cmpedx':'\x39\xd2',
  226.                 'cmpesi':'\x39\xd6',
  227.                 'cmpedi':'\x39\xd7',
  228.                 'cmpebp':'\x39\xd5',
  229.                 'cmpesp':'\x39\xd4',
  230.                 'movVarb':'\x8b\x54\x24%(b)s',
  231.                 'movVarl':'\x8b\x94\x24%(l)s',
  232.                 'movVarPtrb':'\x8d\x54\x24%(b)s',
  233.                 'movVarPtrl':'\x8d\x94\x24%(l)s',
  234.                 'subb':None,
  235.                 'subl':None,
  236.                 'subVarb':None,
  237.                 'subVarl':None,
  238.             },
  239.             'esi': {
  240.                 'value':None,
  241.                 'movb':None,
  242.                 'movw':'\x66\xbe%(w)s',
  243.                 'movl':'\xbe%(l)s',
  244.                 'cmpb':'\x83\xfe%(b)s',
  245.                 'cmpl':'\x81\xfe%(l)s',
  246.                 'zero':'\x31\xf6',
  247.                 'moveax':'\x89\xc6',
  248.                 'movebx':'\x89\xde',
  249.                 'movecx':'\x89\xce',
  250.                 'movedx':'\x89\xd6',
  251.                 'movesi':'',
  252.                 'movedi':'\x89\xfe',
  253.                 'movebp':'\x89\xee',
  254.                 'movesp':'\x89\xe6',
  255.                 'cmpeax':'\x39\xf0',
  256.                 'cmpebx':'\x39\xf3',
  257.                 'cmpecx':'\x39\xf1',
  258.                 'cmpedx':'\x39\xf2',
  259.                 'cmpesi':'\x39\xf6',
  260.                 'cmpedi':'\x39\xf7',
  261.                 'cmpebp':'\x39\xf5',
  262.                 'cmpesp':'\x39\xf4',
  263.                 'movVarb':'\x8b\x74\x24%(b)s',
  264.                 'movVarl':'\x8b\xb4\x24%(l)s',
  265.                 'movVarPtrb':'\x8d\x74\x24%(b)s',
  266.                 'movVarPtrl':'\x8d\xb4\x24%(l)s',
  267.                 'subb':None,
  268.                 'subl':None,
  269.                 'subVarb':None,
  270.                 'subVarl':None,
  271.             },
  272.             'edi': {
  273.                 'value':None,
  274.                 'movb':None,
  275.                 'movw':'\x66\xbf%(w)s',
  276.                 'movl':'\xbf%(l)s',
  277.                 'cmpb':'\x83\xff%(b)s',
  278.                 'cmpl':'\x81\xff%(l)s',
  279.                 'zero':'\x31\xff',
  280.                 'moveax':'\x89\xc7',
  281.                 'movebx':'\x89\xdf',
  282.                 'movecx':'\x89\xcf',
  283.                 'movedx':'\x89\xd7',
  284.                 'movesi':'\x89\xf7',
  285.                 'movedi':'',
  286.                 'movebp':'\x89\xef',
  287.                 'movesp':'\x89\xe7',
  288.                 'cmpeax':'\x39\xf8',
  289.                 'cmpebx':'\x39\xfb',
  290.                 'cmpecx':'\x39\xf9',
  291.                 'cmpedx':'\x39\xfa',
  292.                 'cmpesi':'\x39\xfe',
  293.                 'cmpedi':'\x39\xff',
  294.                 'cmpebp':'\x39\xfd',
  295.                 'cmpesp':'\x39\xfc',
  296.                 'movVarb':'\x8b\x7c\x24%(b)s',
  297.                 'movVarl':'\x8b\xbc\x24%(l)s',
  298.                 'movVarPtrb':'\x8d\x7c\x24%(b)s',
  299.                 'movVarPtrl':'\x8d\xbc\x24%(l)s',
  300.                 'subb':None,
  301.                 'subl':None,
  302.                 'subVarb':None,
  303.                 'subVarl':None,
  304.             },
  305.             'ebp': {
  306.                 'value':None,
  307.                 'movb':None,
  308.                 'movw':'\x66\xbd%(w)s',
  309.                 'movl':'\xbd%(l)s',
  310.                 'cmpb':'\x83\xfd%(b)s',
  311.                 'cmpl':'\x81\xfd%(l)s',
  312.                 'zero':'\x31\xed',
  313.                 'moveax':'\x89\xc5',
  314.                 'movebx':'\x89\xdd',
  315.                 'movecx':'\x89\xcd',
  316.                 'movedx':'\x89\xd5',
  317.                 'movesi':'\x89\xf5',
  318.                 'movedi':'\x89\xfd',
  319.                 'movebp':'',
  320.                 'movesp':'\x89\xe5',
  321.                 'cmpeax':'\x39\xe8',
  322.                 'cmpebx':'\x39\xeb',
  323.                 'cmpecx':'\x39\xe9',
  324.                 'cmpedx':'\x39\xea',
  325.                 'cmpesi':'\x39\xee',
  326.                 'cmpedi':'\x39\xef',
  327.                 'cmpebp':'\x39\xed',
  328.                 'cmpesp':'\x39\xec',
  329.                 'movVarb':'\x8b\x6c\x24%(b)s',
  330.                 'movVarl':'\x8b\xac\x24%(l)s',
  331.                 'movVarPtrb':'\x8d\x6c\x24%(b)s',
  332.                 'movVarPtrl':'\x8d\xac\x24%(l)s',
  333.                 'subb':None,
  334.                 'subl':None,
  335.                 'subVarb':None,
  336.                 'subVarl':None,
  337.             },
  338.             'esp': {
  339.                 'value':None,
  340.                 'movb':None,
  341.                 'movw':'\x66\xbc%(w)s',
  342.                 'movl':'\xbc%(l)s',
  343.                 'cmpb':'\x83\xfc%(b)s',
  344.                 'cmpl':'\x81\xfc%(l)s',
  345.                 'zero':'\x31\xe4',
  346.                 'moveax':'\x89\xc4',
  347.                 'movebx':'\x89\xdc',
  348.                 'movecx':'\x89\xcc',
  349.                 'movedx':'\x89\xd4',
  350.                 'movesi':'\x89\xf4',
  351.                 'movedi':'\x89\xfc',
  352.                 'movebp':'\x89\xec',
  353.                 'movesp':'',
  354.                 'cmpeax':'\x39\xe0',
  355.                 'cmpebx':'\x39\xe3',
  356.                 'cmpecx':'\x39\xe1',
  357.                 'cmpedx':'\x39\xe2',
  358.                 'cmpesi':'\x39\xe6',
  359.                 'cmpedi':'\x39\xe7',
  360.                 'cmpebp':'\x39\xe5',
  361.                 'cmpesp':'\x39\xe4',
  362.                 'movVarb':'\x8b\x64\x24%(b)s',
  363.                 'movVarl':'\x8b\xa4\x24%(l)s',
  364.                 'movVarPtrb':'\x8d\x64\x24%(b)s',
  365.                 'movVarPtrl':'\x8d\xa4\x24%(l)s',
  366.                 'subb':'\x83\xec%(b)s',
  367.                 'subl':'\x81\xec%(l)s',
  368.                 'subVarb':'\x2b\x64\x24%(b)s',
  369.                 'subVarl':'\x2b\xa4\x24%(l)s',
  370.             },
  371.         }
  372.  
  373.         self.reset()
  374.         self.stack = []
  375.  
  376.     def is_value(self, value):
  377.         return type(value) == types.IntType
  378.     
  379.     def is_register(self, value):
  380.         return value in self.registers()
  381.  
  382.     def is_variable(self, value):
  383.         return value.startswith('var')
  384.  
  385.     def is_varpointer(self, value):
  386.         return value.startswith('ptr')
  387.  
  388.     def is_tuple(self, value):
  389.         return type(value) is types.TupleType or type(value) is types.ListType
  390.  
  391.     def reset(self):
  392.         for i in self.opcodes.values():
  393.             i['value'] = None
  394.  
  395.     def nop(self):
  396.         return '\x90'
  397.  
  398.     def zero(self,reg):
  399.         self.setValue(reg,0)
  400.         return self.opcodes[reg]['zero']
  401.  
  402.     def incReg(self,reg):
  403.         return '%c' % (0x40+self.regNum(reg))
  404.  
  405.     def incVar(self,var):
  406.         offset = len(self.stack)*4 - var.offset
  407.  
  408.         if -128 <= offset <= 127:
  409.             return self.opcodes['']['incVarb'] % (offset & 0xff)
  410.         return self.opcodes['']['incVarl'] % struct.pack('<l',offset)
  411.  
  412.     def inc(self, operator):
  413.         if self.is_register(operator):
  414.             return self.incReg(operator)
  415.         if self.is_variable(operator):
  416.             return self.incVar(operator)
  417.         raise Exception, ('incrementing (%s) not yet implemented' % operator)
  418.  
  419.     def decReg(self,reg):
  420.         return '%c' % (0x48+self.regNum(reg))
  421.  
  422.     def decVar(self,var):
  423.         offset = len(self.stack)*4 - var.offset
  424.  
  425.         if -128 <= offset <= 127:
  426.             return self.opcodes['']['decVarb'] % (offset & 0xff)
  427.         return self.opcodes['']['decVarl'] % struct.pack('<l',offset)
  428.  
  429.     def dec(self, operator):
  430.         if self.is_register(operator):
  431.             return self.decReg(operator)
  432.         if self.is_variable(operator):
  433.             return self.decVar(operator)
  434.         raise Exception, ('decrementing (%s) not yet implemented' % operator)
  435.  
  436.     def getValue(self,reg):
  437.         return self.opcodes[reg]['value']
  438.  
  439.     def setValue(self,reg,value):
  440.         self.opcodes[reg]['value'] = value
  441.         
  442.     def findMatch(self,value):
  443.         # find exact match
  444.         for i in self.registers():
  445.             if self.getValue(i) == value:
  446.                 return i
  447.         return None
  448.         
  449.     def popReg(self, reg):
  450.         return '%c' % (0x58+self.regNum(reg))
  451.  
  452.     def pop(self, operator):
  453.         self.unpush(1)
  454.         if self.is_register(operator):
  455.             return self.popReg(operator)
  456.         raise Exception, ('popping non registers (%s) not yet implemented' % value)
  457.  
  458.     def pushReg(self, reg):
  459.         return '%c' % (0x50+self.regNum(reg))
  460.  
  461.     def pushVariable(self, var):
  462.         offset = len(self.stack)*4 - var.offset - 4
  463.  
  464.         if -128 <= offset <= 127:
  465.             return self.opcodes['']['pushVarb'] % (offset & 0xff)
  466.         return self.opcodes['']['pushVarl'] % struct.pack('<l',offset)
  467.         
  468.     def pushVarPtr(self, ptr):
  469.         offset = len(self.stack)*4 - int(ptr[3:]) - 4
  470.  
  471.         if not offset:
  472.             return self.push('esp')
  473.         if -128 <= offset <= 127:
  474.             return self.opcodes['']['pushVarPtrb'] % (offset & 0xff)
  475.         return self.opcodes['']['pushVarPtrl'] % struct.pack('<l',offset)
  476.  
  477.     def pushTuple(self, tuple, notForTemps = ()):
  478.         code = ''
  479.         temps = self.registers()[:]
  480.         to_push = [0]*len(tuple)
  481.         for r in tuple+notForTemps:
  482.         # first pass, removed the used registers from the possible temp regs
  483.             if r in temps: temps.remove(r)
  484.  
  485.         # second pass, mov string or tupples into registers
  486.         for i in range(len(tuple)):
  487.             arg = tuple[i]
  488.             if not (self.is_value(arg) or self.is_register(arg) or self.is_variable(arg)):
  489.                 # either it's a tupple or a string
  490.                 arg = temps[0]
  491.                 del temps[0]
  492.                 code += self.set(arg, tuple[i])
  493.             to_push[i] = arg
  494.  
  495.         # third pass, just push arguments
  496.         for i in range(len(to_push)-1,-1,-1):
  497.             code += self.push(to_push[i])
  498.  
  499.         return code
  500.  
  501.     def pushString(self, string):
  502.         answer = ''
  503.         string += '\x00\x00\x00\x00'[:4-(len(string) % 4)]
  504.         for i in struct.unpack('<%dl' % (len(string)/4), string):
  505.             answer = self.push(i)+answer
  506.         return answer
  507.  
  508.     def push(self,value, notForTemps = ()):
  509.         self.stack.append(value)
  510.  
  511.         if self.is_register(value):
  512.             return self.pushReg(value)
  513.  
  514.         if self.is_value(value):
  515.             # find register with the same value
  516.             match = self.findMatch(value)
  517.             if match: return self.pushReg(match)
  518.  
  519.             if -0x80 <= value < 0x7f:
  520.                 return self.opcodes['']['pushb'] % (value & 0xff)
  521.  
  522.             return self.opcodes['']['pushl'] % struct.pack('<L',value)
  523.  
  524.         if self.is_tuple(value):
  525.             self.unpush(1)
  526.             return self.pushTuple(value, notForTemps = notForTemps)
  527.  
  528.         if self.is_variable(value):
  529.             return self.pushVariable(value)
  530.  
  531.         if self.is_varpointer(value):
  532.             return self.pushVarPtr(value)
  533.  
  534.         self.unpush(1)
  535.         return self.pushString(value)
  536.  
  537.     def varAtTop(self, size = 4):
  538.         return Variable(len(self.stack)*4, size)
  539.     
  540.     def alloc(self,bytes):
  541.         # will allocate from stack and return a var
  542.  
  543.         words = (bytes + 3) / 4
  544.  
  545.         if not words: return ''
  546.  
  547.         self.stack.extend([None] * words)
  548.         bytes = words * 4
  549.  
  550.         b = '%c' % (bytes & 0xff)
  551.         l = struct.pack('<l',bytes)
  552.  
  553.         if -128 <= bytes <= 127:
  554.             code = self.opcodes['esp']['subb'] % vars()
  555.         else:
  556.             code = self.opcodes['esp']['subl'] % vars()
  557.  
  558.         return (code, self.varAtTop(bytes))
  559.  
  560.     def freeVar(self,var):
  561.  
  562.         offset = len(self.stack)*4 - var.offset
  563.  
  564.         b = '%c' % (offset & 0xff)
  565.         l = struct.pack('<l',offset)
  566.         
  567.         if -128 <= offset <= 127:
  568.             return self.opcodes['esp']['subVarb'] % vars()
  569.         else:
  570.             return self.opcodes['esp']['subVarl'] % vars()
  571.  
  572.     def unpush(self, words):
  573.         del self.stack[-words:]
  574.  
  575.     def free(self,bytes):
  576.         # will free some bytes from the top of the stack
  577.         # it's blind to stack's contents
  578.         if self.is_value(bytes):
  579.             words = (bytes + 3) / 4
  580.         else:
  581.             return self.freeVar(bytes)
  582.  
  583.         if not words: return ''
  584.  
  585.         self.unpush(words)
  586.         bytes = -words * 4
  587.  
  588.         b = '%c' % (bytes & 0xff)
  589.         l = struct.pack('<l',bytes)
  590.  
  591.         if -128 <= bytes <= 127:
  592.             code = self.opcodes['esp']['subb'] % vars()
  593.         else:
  594.             code = self.opcodes['esp']['subl'] % vars()
  595.  
  596.         return code
  597.  
  598.     def save(self,reg):
  599.         return (self.push(reg), self.varAtTop())
  600.  
  601.     def setReg(self,dest,src):
  602.         if self.getValue(src) != None and self.getValue(src) == self.getValue(dest):
  603.             return ''
  604.         
  605.         self.setValue(dest,self.getValue(src))
  606.         return self.opcodes[dest]['mov'+src]
  607.  
  608.     def setVar(self,reg,var):
  609.  
  610.         self.setValue(reg,var)
  611.  
  612.         offset = len(self.stack)*4 - var.offset
  613.  
  614.         b = '%c' % (offset & 0xff)
  615.         l = struct.pack('<l',offset)
  616.         
  617.         if -128 <= offset <= 127:
  618.             return self.opcodes[reg]['movVarb'] % vars()
  619.         else:
  620.             return self.opcodes[reg]['movVarl'] % vars()
  621.         
  622.     def setVarPtr(self,reg,offset):
  623.         self.setValue(reg,offset)
  624.         
  625.         offset = int(offset[3:])
  626.         offset = len(self.stack)*4 - offset
  627.  
  628.         if not offset:
  629.             return self.opcodes[reg]['movesp']
  630.  
  631.         b = '%c' % (offset & 0xff)
  632.         l = struct.pack('<l',offset)
  633.  
  634.         if -128 <= offset <= 127:
  635.             return self.opcodes[reg]['movVarPtrb'] % vars()
  636.         else:
  637.             return self.opcodes[reg]['movVarPtrl'] % vars()
  638.  
  639.     """
  640.     This is not working, because it calls micro.set('ptrXX','register')
  641.  
  642.     def setTuple(self,reg,tuple):
  643.         code,buf = self.alloc(len(tuple)*4)
  644.         for i in range(len(tuple)):
  645.             code += self.set(reg,tuple[i])
  646.             code += self.set((buf+i*4).addr(),reg)
  647.         code += self.set(reg,buf.addr())
  648.         return code
  649.     """
  650.  
  651.     def setString(self,reg,string):
  652.         answer = self.set(reg,'esp')
  653.         answer = self.push(string)+answer
  654.         return answer
  655.  
  656.     def set(self,reg,newValue):
  657.  
  658.         value   = self.getValue(reg)
  659.  
  660.         if value == newValue:
  661.             return ''
  662.  
  663.         # find another register with the same value
  664.         match = self.findMatch(newValue)
  665.         if match: return self.setReg(reg,match)
  666.         
  667.         if not self.is_value(newValue):
  668.             # if int() fails, then newValue is a string
  669.             if self.is_register(newValue):
  670.                 # moving from a register
  671.                 return self.setReg(reg,newValue)
  672.             else:
  673.                 # setting a tuple or list
  674.                 if self.is_tuple(newValue):
  675.                     return self.setTuple(reg,newValue)
  676.                 
  677.                 # setting a Variable or pointer to Variable
  678.                 if self.is_variable(newValue):
  679.                     return self.setVar(reg,newValue)
  680.                 if self.is_varpointer(newValue):
  681.                     return self.setVarPtr(reg,newValue)
  682.  
  683.                 # setting a litteral string
  684.                 return self.setString(reg,newValue)
  685.  
  686.         if newValue == 0:           # even if other reg is zero:
  687.             return self.zero(reg)   # xor has 2 bytes as well as mov reg,reg
  688.  
  689.         b = '%c' % (newValue & 0xff)
  690.         w = struct.pack('<h',newValue & 0xffff)
  691.         l = struct.pack('<L',newValue)
  692.  
  693.         opcodes = self.opcodes[reg]
  694.         answer  = None
  695.  
  696.         # if current value is a number
  697.         if self.is_value(value) and (newValue & ~0xff) == (value & ~0xff) and opcodes['movb']:
  698.             answer = opcodes['movb'] % vars()
  699.             
  700.         elif self.is_value(value) and (newValue & ~0xffff) == (value & ~0xffff):
  701.             answer = opcodes['movw'] % vars()
  702.         else:
  703.             if (0 <= newValue < 0x100):
  704.                 answer = self.push(newValue)+self.pop(reg)
  705.             elif 0x100 <= newValue < 0x10000:
  706.                 answer = self.zero(reg)+self.set(reg,newValue)
  707.  
  708.         self.setValue(reg,newValue)
  709.         if answer:
  710.             return answer
  711.         else:
  712.             return opcodes['movl'] % vars()
  713.  
  714.     # comparitions
  715.     def cmpReg(self,left,right):
  716. #        if self.getValue(src) != None and self.getValue(src) == self.getValue(dest):
  717. #            return ''
  718. #        
  719.         return self.opcodes[left]['cmp'+right]
  720.  
  721.     def cmpValue(self, reg, value):
  722. #        if self.getValue(reg) == value:
  723. #            return ''
  724.         b = '%c' % (value & 0xff)
  725.         l = struct.pack('<L',value)
  726.  
  727.         if (-0x80 <= value < 0x7f):
  728.             return self.opcodes[reg]['cmpb'] % vars()
  729.  
  730.         return self.opcodes[reg]['cmpl'] % vars()
  731.  
  732.     def cmpRegVar(self, reg, var):
  733.         # compares a register and a variable
  734.         raise Exception, "Not implemented yet"
  735.  
  736.     def cmpVarValue(self, var, value):
  737.         # compares a variable with an immediate value
  738.         if -128 <= value <= 127:
  739.             # the value is a byte
  740.             key = 'cmpb'
  741.             value &= 0xff
  742.         else:
  743.             key = 'cmpl'
  744.             value = struct.pack('<l',value)
  745.  
  746.         offset = len(self.stack)*4 - var.offset
  747.  
  748.         if -128 <= offset <= 127:
  749.             # variable's offset is a byte
  750.             return self.opcodes[''][key+'Varb'] % (offset & 0xff, value)
  751.         else:
  752.             return self.opcodes[''][key+'Varl'] % (struct.pack('<l', offset), value)
  753.         
  754.  
  755.     def cmp(self, left, right):
  756.         if self.is_register(left):
  757.             if self.is_value(right):
  758.                 return self.cmpValue(left,right)
  759.             if self.is_register(right):
  760.                 return self.cmpReg(left,right)
  761.             if self.is_variable(right):
  762.                 return self.cmpReg(left,right)
  763.         else:
  764.             if self.is_value(right):
  765.                 return self.cmpVarValue(left,right)
  766. #       the problem with this is that an if(var, reg) must have the oposite condition
  767. #            if self.is_register(right):
  768. #                return self.cmpRegVar(right,left)
  769.  
  770.         raise Exception, "Invalid comparision between %s and %s" % (left, right)
  771.  
  772.     # jumps
  773.     def jumpRel(self,delta,condition = ''):
  774.         # the jump is relative to the first byte of the jump
  775.  
  776.         b = '%c' % (delta - 2 & 0xff)
  777.         l = struct.pack('<L',delta-5)
  778.  
  779.         if -128 < delta-2 < 127:
  780.             return self.opcodes['']['jmpb'+condition] % vars()
  781.         else:
  782.             if condition:
  783.                 raise Exception, 'long conditional jumps not implementer yet'
  784.             return self.opcodes['']['jmpl'] % vars()
  785.         
  786.     def opositeCondition(self, condition):
  787.         return self.opcodes['']['!'+condition]
  788.  
  789.     def callVar(self, var):
  790.         offset = len(self.stack)*4 - var.offset
  791.  
  792.         if -128 <= offset <= 127:
  793.             # variable's offset is a byte
  794.             return self.opcodes['']['callVarb'] % (offset & 0xff)
  795.         else:
  796.             return self.opcodes['']['callVarl'] % (struct.pack('<l', offset))
  797.  
  798.     def callRel(self,delta):
  799.         # the jump is relative to the first byte of the jump
  800.  
  801.         return '\xe8'+(struct.pack('<l',delta-5))
  802.  
  803.     def jumpReg(self, reg):
  804.         return '\xff%c' % (0xe0+self.regNum(reg))
  805.  
  806.     def callReg(self, reg):
  807.         return '\xff%c' % (0xd0+self.regNum(reg))
  808.  
  809.     def call(self, dest):
  810.         # XXX: next reset should not be reset but, for example,
  811.         # when calling a function, the registers should be set
  812.         # as left by the called function (some changed some not)
  813.  
  814.         self.reset()
  815.         if self.is_value(dest):
  816.             return self.callRel(dest)
  817.         if self.is_variable(dest):
  818.             return self.callVar(dest)
  819.         if self.is_register(dest):
  820.             return self.callReg(dest)
  821.         raise Exception, ("Unsupported call type, calling (%s)" % dest)
  822.         
  823.     def ret(self,n = 0):
  824.         if n:
  825.             return '\xc2'+struct.pack('<h',n)
  826.         else:
  827.             return '\xc3'
  828.  
  829.     def regNum(self, reg):
  830.         return self.registers().index(reg)
  831.         
  832.     # interactive utils
  833.     def registers(self):
  834.         return self._registers
  835.     
  836. class Syscall:
  837.     def __init__(self,micro):
  838.         self.micro = micro
  839.  
  840.     def call(self, name, args = ()):
  841.         code = self.setArgs(args)
  842.         code += self.syscall(self.syscalls[name])
  843.         
  844.         return code, self.answer()
  845.  
  846. class Linuxx86Syscall(Syscall):
  847.     microClass = Microx86
  848.     syscalls = {
  849.         'exit':   1,
  850.         'fork':   2,
  851.         'read':   3,
  852.         'write':   4,
  853.         'open':   5,
  854.         'close':   6,
  855.         'waitpid':   7,
  856.         'creat':   8,
  857.         'link':   9,
  858.         'unlink':  10,
  859.         'execve':  11,
  860.         'chdir':  12,
  861.         'time':  13,
  862.         'mknod':  14,
  863.         'chmod':  15,
  864.         'lchown':  16,
  865.         'break':  17,
  866.         'oldstat':  18,
  867.         'lseek':  19,
  868.         'getpid':  20,
  869.         'mount':  21,
  870.         'umount':  22,
  871.         'setuid':  23,
  872.         'getuid':  24,
  873.         'stime':  25,
  874.         'ptrace':  26,
  875.         'alarm':  27,
  876.         'oldfstat':  28,
  877.         'pause':  29,
  878.         'utime':  30,
  879.         'stty':  31,
  880.         'gtty':  32,
  881.         'access':  33,
  882.         'nice':  34,
  883.         'ftime':  35,
  884.         'sync':  36,
  885.         'kill':  37,
  886.         'rename':  38,
  887.         'mkdir':  39,
  888.         'rmdir':  40,
  889.         'dup':  41,
  890.         'pipe':  42,
  891.         'times':  43,
  892.         'prof':  44,
  893.         'brk':  45,
  894.         'setgid':  46,
  895.         'getgid':  47,
  896.         'signal':  48,
  897.         'geteuid':  49,
  898.         'getegid':  50,
  899.         'acct':  51,
  900.         'umount2':  52,
  901.         'lock':  53,
  902.         'ioctl':  54,
  903.         'fcntl':  55,
  904.         'mpx':  56,
  905.         'setpgid':  57,
  906.         'ulimit':  58,
  907.         'oldolduname':  59,
  908.         'umask':  60,
  909.         'chroot':  61,
  910.         'ustat':  62,
  911.         'dup2':  63,
  912.         'getppid':  64,
  913.         'getpgrp':  65,
  914.         'setsid':  66,
  915.         'sigaction':  67,
  916.         'sgetmask':  68,
  917.         'ssetmask':  69,
  918.         'setreuid':  70,
  919.         'setregid':  71,
  920.         'sigsuspend':  72,
  921.         'sigpending':  73,
  922.         'sethostname':  74,
  923.         'setrlimit':  75,
  924.         'getrlimit':  76,
  925.         'getrusage':  77,
  926.         'gettimeofday':  78,
  927.         'settimeofday':  79,
  928.         'getgroups':  80,
  929.         'setgroups':  81,
  930.         'select':  82,
  931.         'symlink':  83,
  932.         'oldlstat':  84,
  933.         'readlink':  85,
  934.         'uselib':  86,
  935.         'swapon':  87,
  936.         'reboot':  88,
  937.         'readdir':  89,
  938.         'mmap':  90,
  939.         'munmap':  91,
  940.         'truncate':  92,
  941.         'ftruncate':  93,
  942.         'fchmod':  94,
  943.         'fchown':  95,
  944.         'getpriority':  96,
  945.         'setpriority':  97,
  946.         'profil':  98,
  947.         'statfs':  99,
  948.         'fstatfs': 100,
  949.         'ioperm': 101,
  950.         'socketcall': 102,
  951.         'syslog': 103,
  952.         'setitimer': 104,
  953.         'getitimer': 105,
  954.         'stat': 106,
  955.         'lstat': 107,
  956.         'fstat': 108,
  957.         'olduname': 109,
  958.         'iopl': 110,
  959.         'vhangup': 111,
  960.         'idle': 112,
  961.         'vm86old': 113,
  962.         'wait4': 114,
  963.         'swapoff': 115,
  964.         'sysinfo': 116,
  965.         'ipc': 117,
  966.         'fsync': 118,
  967.         'sigreturn': 119,
  968.         'clone': 120,
  969.         'setdomainname': 121,
  970.         'uname': 122,
  971.         'modify_ldt': 123,
  972.         'adjtimex': 124,
  973.         'mprotect': 125,
  974.         'sigprocmask': 126,
  975.         'create_module': 127,
  976.         'init_module': 128,
  977.         'delete_module': 129,
  978.         'get_kernel_syms': 130,
  979.         'quotactl': 131,
  980.         'getpgid': 132,
  981.         'fchdir': 133,
  982.         'bdflush': 134,
  983.         'sysfs': 135,
  984.         'personality': 136,
  985.         'afs_syscall': 137,
  986.         'setfsuid': 138,
  987.         'setfsgid': 139,
  988.         '_llseek': 140,
  989.         'getdents': 141,
  990.         '_newselect': 142,
  991.         'flock': 143,
  992.         'msync': 144,
  993.         'readv': 145,
  994.         'writev': 146,
  995.         'getsid': 147,
  996.         'fdatasync': 148,
  997.         '_sysctl': 149,
  998.         'mlock': 150,
  999.         'munlock': 151,
  1000.         'mlockall': 152,
  1001.         'munlockall': 153,
  1002.         'sched_setparam': 154,
  1003.         'sched_getparam': 155,
  1004.         'sched_setscheduler': 156,
  1005.         'sched_getscheduler': 157,
  1006.         'sched_yield': 158,
  1007.         'sched_get_priority_max': 159,
  1008.         'sched_get_priority_min': 160,
  1009.         'sched_rr_get_interval': 161,
  1010.         'nanosleep': 162,
  1011.         'mremap': 163,
  1012.         'setresuid': 164,
  1013.         'getresuid': 165,
  1014.         'vm86': 166,
  1015.         'query_module': 167,
  1016.         'poll': 168,
  1017.         'nfsservctl': 169,
  1018.         'setresgid': 170,
  1019.         'getresgid': 171,
  1020.         'prctl':172,
  1021.         'rt_sigreturn': 173,
  1022.         'rt_sigaction': 174,
  1023.         'rt_sigprocmask': 175,
  1024.         'rt_sigpending': 176,
  1025.         'rt_sigtimedwait': 177,
  1026.         'rt_sigqueueinfo': 178,
  1027.         'rt_sigsuspend': 179,
  1028.         'pread': 180,
  1029.         'pwrite': 181,
  1030.         'chown': 182,
  1031.         'getcwd': 183,
  1032.         'capget': 184,
  1033.         'capset': 185,
  1034.         'sigaltstack': 186,
  1035.         'sendfile': 187,
  1036.         'getpmsg': 188,
  1037.         'putpmsg': 189,
  1038.         'vfork': 190,
  1039.         'ugetrlimit': 191,
  1040.         'mmap2': 192,
  1041.         'truncate64': 193,
  1042.         'ftruncate64': 194,
  1043.         'stat64': 195,
  1044.         'lstat64': 196,
  1045.         'fstat64': 197,
  1046.         'lchown32': 198,
  1047.         'getuid32': 199,
  1048.         'getgid32': 200,
  1049.         'geteuid32': 201,
  1050.         'getegid32': 202,
  1051.         'setreuid32': 203,
  1052.         'setregid32': 204,
  1053.         'getgroups32': 205,
  1054.         'setgroups32': 206,
  1055.         'fchown32': 207,
  1056.         'setresuid32': 208,
  1057.         'getresuid32': 209,
  1058.         'setresgid32': 210,
  1059.         'getresgid32': 211,
  1060.         'chown32': 212,
  1061.         'setuid32': 213,
  1062.         'setgid32': 214,
  1063.         'setfsuid32': 215,
  1064.         'setfsgid32': 216,
  1065.         'pivot_root': 217,
  1066.         'mincore': 218,
  1067.         'madvise': 219,
  1068.         'madvise1': 219,
  1069.         'getdents64': 220,
  1070.         'fcntl64': 221,
  1071.         'security': 223,
  1072.         'gettid': 224,
  1073.         'readahead': 225,
  1074.         'setxattr': 226,
  1075.         'lsetxattr': 227,
  1076.         'fsetxattr': 228,
  1077.         'getxattr': 229,
  1078.         'lgetxattr': 230,
  1079.         'fgetxattr': 231,
  1080.         'listxattr': 232,
  1081.         'llistxattr': 233,
  1082.         'flistxattr': 234,
  1083.         'removexattr': 235,
  1084.         'lremovexattr': 236,
  1085.         'fremovexattr': 237,
  1086.         'tkill': 238,
  1087.         'sendfile64': 239,
  1088.         'futex': 240,
  1089.         'sched_setaffinity': 241,
  1090.         'sched_getaffinity': 242,
  1091.         'set_thread_area ': 243,
  1092.     }
  1093.     # socket calls
  1094.     socketcalls= {
  1095.         'socket': 1,
  1096.         'bind': 2,
  1097.         'connect': 3,
  1098.         'listen': 4,
  1099.         'accept': 5,
  1100.         'getsockname': 6,
  1101.         'getpeername': 7,
  1102.         'socketpair': 8,
  1103.         'send': 9,
  1104.         'recv': 10,
  1105.         'sendto': 11,
  1106.         'recvfrom': 12,
  1107.         'shutdown': 13,
  1108.         'setsockopt': 14,
  1109.         'getsockopt': 15,
  1110.         'sendmsg': 16,
  1111.         'recvmsg': 17
  1112.     }
  1113.  
  1114.     def __init__(self,micro):
  1115.         Syscall.__init__(self,micro)
  1116.         self.args  = ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp']
  1117.  
  1118.     def setArg(self, argNumber, value):
  1119.         return self.micro.set(self.args[argNumber],value)
  1120.  
  1121.     def setArgs(self, args = ()):
  1122.         code = ''
  1123.         for i in range(len(args)):
  1124.             code += self.setArg(i+1,args[i])
  1125.         
  1126.         return code
  1127.  
  1128.     def call(self, name, args = ()):
  1129.         if self.socketcalls.has_key(name):
  1130.             return self.socketCall(name,args)
  1131.         else:
  1132.             return Syscall.call(self,name,args)
  1133.  
  1134.     def syscall(self, number):
  1135.         answer = self.setArg(0,number)+'\xcd\x80'   # int $0x80
  1136.         self.micro.setValue(self.args[0],None)
  1137.         return answer
  1138.  
  1139.     def socketCall(self,name,args):
  1140.         code = ''
  1141.         code += self.micro.push(args)
  1142.         sysCode, answer = self.call('socketcall',
  1143.             (self.socketcalls[name],self.micro.varAtTop().addr()))
  1144.         code += sysCode
  1145.         code += self.micro.free(4*len(args))
  1146.         return code, answer
  1147.         
  1148.     def answer(self):
  1149.         return 'eax'
  1150.  
  1151. class StackBasedSyscall(Syscall):
  1152.     def __init__(self,micro):
  1153.         self.micro = micro
  1154.  
  1155.     def setArgs(self, args = (), notForTemps = ()):
  1156.         return self.micro.push(args, notForTemps = notForTemps)
  1157.  
  1158.     def answer(self):
  1159.         return 'eax'
  1160.  
  1161. class OpenBSDx86Syscall(StackBasedSyscall):
  1162.     microClass = Microx86
  1163.     syscalls = {
  1164.         'syscall': 0,
  1165.         'exit': 1,
  1166.         'fork': 2,
  1167.         'read': 3,
  1168.         'write': 4,
  1169.         'open': 5,
  1170.         'close': 6,
  1171.         'wait4': 7,
  1172.         'link': 9,
  1173.         'unlink': 10,
  1174.         'chdir': 12,
  1175.         'fchdir': 13,
  1176.         'mknod': 14,
  1177.         'chmod': 15,
  1178.         'chown': 16,
  1179.         'break': 17,
  1180.         'ogetfsstat': 18,
  1181.         'getpid': 20,
  1182.         'mount': 21,
  1183.         'unmount': 22,
  1184.         'setuid': 23,
  1185.         'getuid': 24,
  1186.         'geteuid': 25,
  1187.         'ptrace': 26,
  1188.         'recvmsg': 27,
  1189.         'sendmsg': 28,
  1190.         'recvfrom': 29,
  1191.         'accept': 30,
  1192.         'getpeername': 31,
  1193.         'getsockname': 32,
  1194.         'access': 33,
  1195.         'chflags': 34,
  1196.         'fchflags': 35,
  1197.         'sync': 36,
  1198.         'kill': 37,
  1199.         'getppid': 39,
  1200.         'dup': 41,
  1201.         'opipe': 42,
  1202.         'getegid': 43,
  1203.         'profil': 44,
  1204.         'ktrace': 45,
  1205.         'sigaction': 46,
  1206.         'getgid': 47,
  1207.         'sigprocmask': 48,
  1208.         'getlogin': 49,
  1209.         'setlogin': 50,
  1210.         'acct': 51,
  1211.         'sigpending': 52,
  1212.         'sigaltstack': 53,
  1213.         'ioctl': 54,
  1214.         'reboot': 55,
  1215.         'revoke': 56,
  1216.         'symlink': 57,
  1217.         'readlink': 58,
  1218.         'execve': 59,
  1219.         'umask': 60,
  1220.         'chroot': 61,
  1221.         'omsync': 65,
  1222.         'vfork': 66,
  1223.         'sbrk': 69,
  1224.         'sstk': 70,
  1225.         'vadvise': 72,
  1226.         'munmap': 73,
  1227.         'mprotect': 74,
  1228.         'madvise': 75,
  1229.         'mincore': 78,
  1230.         'getgroups': 79,
  1231.         'setgroups': 80,
  1232.         'getpgrp': 81,
  1233.         'setpgid': 82,
  1234.         'setitimer': 83,
  1235.         'swapon': 85,
  1236.         'getitimer': 86,
  1237.         'dup2': 90,
  1238.         'fcntl': 92,
  1239.         'select': 93,
  1240.         'fsync': 95,
  1241.         'setpriority': 96,
  1242.         'socket': 97,
  1243.         'connect': 98,
  1244.         'getpriority': 100,
  1245.         'sigreturn': 103,
  1246.         'bind': 104,
  1247.         'setsockopt': 105,
  1248.         'listen': 106,
  1249.         'sigsuspend': 111,
  1250.         'gettimeofday': 116,
  1251.         'getrusage': 117,
  1252.         'getsockopt': 118,
  1253.         'readv': 120,
  1254.         'writev': 121,
  1255.         'settimeofday': 122,
  1256.         'fchown': 123,
  1257.         'fchmod': 124,
  1258.         'rename': 128,
  1259.         'flock': 131,
  1260.         'mkfifo': 132,
  1261.         'sendto': 133,
  1262.         'shutdown': 134,
  1263.         'socketpair': 135,
  1264.         'mkdir': 136,
  1265.         'rmdir': 137,
  1266.         'utimes': 138,
  1267.         'adjtime': 140,
  1268.         'setsid': 147,
  1269.         'quotactl': 148,
  1270.         'nfssvc': 155,
  1271.         'ostatfs': 157,
  1272.         'ofstatfs': 158,
  1273.         'getfh': 161,
  1274.         'sysarch': 165,
  1275.         'pread': 173,
  1276.         'pwrite': 174,
  1277.         'ntp_gettime': 175,
  1278.         'ntp_adjtime': 176,
  1279.         'setgid': 181,
  1280.         'setegid': 182,
  1281.         'seteuid': 183,
  1282.         'lfs_bmapv': 184,
  1283.         'lfs_markv': 185,
  1284.         'lfs_segclean': 186,
  1285.         'lfs_segwait': 187,
  1286.         'stat': 188,
  1287.         'fstat': 189,
  1288.         'lstat': 190,
  1289.         'pathconf': 191,
  1290.         'fpathconf': 192,
  1291.         'swapctl': 193,
  1292.         'getrlimit': 194,
  1293.         'setrlimit': 195,
  1294.         'getdirentries': 196,
  1295.         'mmap': 197,
  1296.         '__syscall': 198,
  1297.         'lseek': 199,
  1298.         'truncate': 200,
  1299.         'ftruncate': 201,
  1300.         '__sysctl': 202,
  1301.         'mlock': 203,
  1302.         'munlock': 204,
  1303.         'undelete': 205,
  1304.         'futimes': 206,
  1305.         'getpgid': 207,
  1306.         'xfspioctl': 208,
  1307.         '__osemctl': 220,
  1308.         'semget': 221,
  1309.         'semop': 222,
  1310.         'omsgctl': 224,
  1311.         'msgget': 225,
  1312.         'msgsnd': 226,
  1313.         'msgrcv': 227,
  1314.         'shmat': 228,
  1315.         'oshmctl': 229,
  1316.         'shmdt': 230,
  1317.         'shmget': 231,
  1318.         'clock_gettime': 232,
  1319.         'clock_settime': 233,
  1320.         'clock_getres': 234,
  1321.         'nanosleep': 240,
  1322.         'minherit': 250,
  1323.         'rfork': 251,
  1324.         'poll': 252,
  1325.         'issetugid': 253,
  1326.         'lchown': 254,
  1327.         'getsid': 255,
  1328.         'msync': 256,
  1329.         '__semctl': 257,
  1330.         'shmctl': 258,
  1331.         'msgctl': 259,
  1332.         'getfsstat': 260,
  1333.         'statfs': 261,
  1334.         'fstatfs': 262,
  1335.         'pipe': 263,
  1336.         'fhopen': 264,
  1337.         'fhstat': 265,
  1338.         'fhstatfs': 266,
  1339.         'preadv': 267,
  1340.         'pwritev': 268,
  1341.         'kqueue': 269,
  1342.         'kevent': 270,
  1343.         'mlockall': 271,
  1344.         'munlockall': 272,
  1345.     }
  1346.     def syscall(self, number):
  1347.         answer = self.micro.push('eax')
  1348.         answer += self.micro.set('eax',number)+'\xcd\x80'   # int $0x80
  1349.         self.micro.setValue('eax',None)
  1350.         return answer
  1351.  
  1352. class Solarisx86Syscall(StackBasedSyscall):
  1353.     microClass = Microx86
  1354.     syscalls = {
  1355.         'syscall': 0,
  1356.         'exit': 1,
  1357.         'fork': 2,
  1358.         'read': 3,
  1359.         'write': 4,
  1360.         'open': 5,
  1361.         'close': 6,
  1362.         'wait': 7,
  1363.         'creat': 8,
  1364.         'link': 9,
  1365.         'unlink': 10,
  1366.         'exec': 11,
  1367.         'chdir': 12,
  1368.         'time': 13,
  1369.         'mknod': 14,
  1370.         'chmod': 15,
  1371.         'chown': 16,
  1372.         'brk':  17,
  1373.         'stat': 18,
  1374.         'lseek': 19,
  1375.         'getpid': 20,
  1376.         'mount': 21,
  1377.         'umount': 22,
  1378.         'setuid': 23,
  1379.         'getuid': 24,
  1380.         'stime': 25,
  1381.         'pcsample': 26,
  1382.         'alarm': 27,
  1383.         'fstat': 28,
  1384.         'pause': 29,
  1385.         'utime': 30,
  1386.         'stty': 31,
  1387.         'gtty': 32,
  1388.         'access': 33,
  1389.         'nice': 34,
  1390.         'statfs': 35,
  1391.         'sync': 36,
  1392.         'kill': 37,
  1393.         'fstatfs': 38,
  1394.         'pgrpsys': 39,
  1395.               #
  1396.               # subcodes:
  1397.               # getpgrp()   :: syscall(39,0)
  1398.               # setpgrp()   :: syscall(39,1)
  1399.               # getsid(pid)   :: syscall(39,2,pid)
  1400.               # setsid()   :: syscall(39,3)
  1401.               # getpgid(pid)   :: syscall(39,4,pid)
  1402.               # setpgid(pid,pgid) :: syscall(39,5,pid,pgid)
  1403.               #
  1404.         'xenix': 40,
  1405.               #
  1406.               # subcodes:
  1407.               # syscall(40, code, ...)
  1408.               #
  1409.         'dup':  41,
  1410.         'pipe': 42,
  1411.         'times': 43,
  1412.         'profil': 44,
  1413.         'plock': 45,
  1414.         'setgid': 46,
  1415.         'getgid': 47,
  1416.         'signal': 48,
  1417.               #
  1418.               # subcodes:
  1419.               # signal(sig, f) :: signal(sig, f)    ((sig&SIGNO_MASK) == sig)
  1420.               # sigset(sig, f) :: signal(sig|SIGDEFER, f)
  1421.               # sighold(sig)   :: signal(sig|SIGHOLD)
  1422.               # sigrelse(sig)  :: signal(sig|SIGRELSE)
  1423.               # sigignore(sig) :: signal(sig|SIGIGNORE)
  1424.               # sigpause(sig)  :: signal(sig|SIGPAUSE)
  1425.               # see <sys/signal.h>
  1426.               #
  1427.         'msgsys': 49,
  1428.               #
  1429.               # subcodes:
  1430.               # msgget(...)  :: msgsys(0, ...)
  1431.               # msgctl(...)  :: msgsys(1, ...)
  1432.               # msgrcv(...)  :: msgsys(2, ...)
  1433.               # msgsnd(...)  :: msgsys(3, ...)
  1434.               # msgids(...)  :: msgsys(4, ...)
  1435.               # msgsnap(...) :: msgsys(5, ...)
  1436.               # see <sys/msg.h>
  1437.               #
  1438.         'syssun': 50,
  1439.         'sysi86': 50,
  1440.               #
  1441.               # subcodes:
  1442.               # syssun(code, ...)
  1443.               # see <sys/sys3b.h>
  1444.               #
  1445.         'acct': 51,
  1446.         'shmsys': 52,
  1447.               #
  1448.               # subcodes:
  1449.               # shmat (...) :: shmsys(0, ...)
  1450.               # shmctl(...) :: shmsys(1, ...)
  1451.               # shmdt (...) :: shmsys(2, ...)
  1452.               # shmget(...) :: shmsys(3, ...)
  1453.               # shmids(...) :: shmsys(4, ...)
  1454.               # see <sys/shm.h>
  1455.               #
  1456.         'semsys': 53,
  1457.               #
  1458.               # subcodes:
  1459.               # semctl(...) :: semsys(0, ...)
  1460.               # semget(...) :: semsys(1, ...)
  1461.               # semop (...) :: semsys(2, ...)
  1462.               # semids(...) :: semsys(3, ...)
  1463.               # semtimedop(...) :: semsys(4, ...)
  1464.               # see <sys/sem.h>
  1465.               #
  1466.         'ioctl': 54,
  1467.         'uadmin': 55,
  1468.               # 56 reserved for exch() 
  1469.         'utssys': 57,
  1470.               #
  1471.               #subcodes (third argument):
  1472.               # uname(obuf)  (obsolete)   :: syscall(57, obuf, ign, 0)
  1473.               #     subcode 1 unused
  1474.               # ustat(dev, obuf)   :: syscall(57, obuf, dev, 2)
  1475.               # fusers(path, flags, obuf) :: syscall(57, path, flags, 3, obuf)
  1476.               # see <sys/utssys.h>
  1477.               #
  1478.         'fdsync': 58,
  1479.         'execve': 59,
  1480.         'umask': 60,
  1481.         'chroot': 61,
  1482.         'fcntl': 62,
  1483.         'ulimit': 63,
  1484.               # 64-69 reserved for UNIX PC
  1485.         'tasksys': 70,
  1486.               #
  1487.               # subcodes:
  1488.               #  settaskid(...) :: tasksys(0, ...)
  1489.               #  gettaskid(...) :: tasksys(1, ...)
  1490.               #  getprojid(...) :: tasksys(2, ...)
  1491.               #
  1492.         'acctctl': 71,
  1493.         'exacctsys': 72,
  1494.               #
  1495.               # subcodes:
  1496.               #  getacct(...) :: exacct(0, ...)
  1497.               #  putacct(...) :: exacct(1, ...)
  1498.               #  wracct(...) :: exacct(2, ...)
  1499.               # 
  1500.         'reserved_73': 73, # 73 reserved
  1501.         'reserved_74': 74, # 74 reserved
  1502.         'reserved_75': 75, # 75 reserved
  1503.         'reserved_76': 76, # 76 reserved
  1504.         'reserved_77': 77, # 77 reserved
  1505.         'reserved_78': 78, # 78 reserved
  1506.         'rmdir': 79,
  1507.         'mkdir': 80,
  1508.         'getdents': 81,
  1509.               # 82 not used, was libattach
  1510.               # 83 not used, was libdetach
  1511.         'sysfs': 84,
  1512.               #
  1513.               # subcodes:
  1514.               # sysfs(code, ...)
  1515.               # see <sys/fstyp.h>
  1516.               # 
  1517.         'getmsg': 85,
  1518.         'putmsg': 86,
  1519.         'poll': 87,
  1520.  
  1521.         'lstat': 88,
  1522.         'symlink': 89,
  1523.         'readlink': 90,
  1524.         'setgroups': 91,
  1525.         'getgroups': 92,
  1526.         'fchmod': 93,
  1527.         'fchown': 94,
  1528.         'sigprocmask': 95,
  1529.         'sigsuspend': 96,
  1530.         'sigaltstack': 97,
  1531.         'sigaction': 98,
  1532.         'sigpending': 99,
  1533.               #
  1534.               # subcodes:
  1535.               #   subcode 0 unused
  1536.               # sigpending(...) :: syscall(99, 1, ...)
  1537.               # sigfillset(...) :: syscall(99, 2, ...)
  1538.               # 
  1539.         'context': 100,
  1540.               #
  1541.               # subcodes:
  1542.               # getcontext(...) :: syscall(100, 0, ...)
  1543.               # setcontext(...) :: syscall(100, 1, ...)
  1544.               # 
  1545.         'evsys': 101,
  1546.         'evtrapret': 102,
  1547.         'statvfs': 103,
  1548.         'fstatvfs': 104,
  1549.         'getloadavg': 105,
  1550.         'nfssys': 106,
  1551.         'waitsys': 107,
  1552.         'sigsendsys': 108,
  1553.         'hrtsys': 109,
  1554.         'acancel': 110,
  1555.         'async': 111,
  1556.         'priocntlsys': 112,
  1557.         'pathconf': 113,
  1558.         'mincore': 114,
  1559.         'mmap': 115,
  1560.         'mprotect': 116,
  1561.         'munmap': 117,
  1562.         'fpathconf': 118,
  1563.         'vfork': 119,
  1564.         'fchdir': 120,
  1565.         'readv': 121,
  1566.         'writev': 122,
  1567.         'xstat': 123,
  1568.         'lxstat': 124,
  1569.         'fxstat': 125,
  1570.         'xmknod': 126,
  1571.         'clocal': 127,
  1572.         'setrlimit': 128,
  1573.         'getrlimit': 129,
  1574.         'lchown': 130,
  1575.         'memcntl': 131,
  1576.         'getpmsg': 132,
  1577.         'putpmsg': 133,
  1578.         'rename': 134,
  1579.         'uname': 135,
  1580.         'setegid': 136,
  1581.         'sysconfig': 137,
  1582.         'adjtime': 138,
  1583.         'systeminfo': 139,
  1584.         'seteuid': 141,
  1585.         'vtrace': 142,
  1586.         'fork1': 143,
  1587.         'sigtimedwait': 144,
  1588.         'lwp_info': 145,
  1589.         'yield': 146,
  1590.         'lwp_sema_wait': 147,
  1591.         'lwp_sema_post': 148,
  1592.         'lwp_sema_trywait': 149,
  1593.         'corectl': 151,
  1594.         'modctl': 152,
  1595.         'fchroot': 153,
  1596.         'utimes': 154,
  1597.         'vhangup': 155,
  1598.         'gettimeofday': 156,
  1599.         'getitimer': 157,
  1600.         'setitimer': 158,
  1601.         'lwp_create': 159,
  1602.         'lwp_exit': 160,
  1603.         'lwp_suspend': 161,
  1604.         'lwp_continue': 162,
  1605.         'lwp_kill': 163,
  1606.         'lwp_self': 164,
  1607.         'lwp_setprivate': 165,
  1608.         'lwp_getprivate': 166,
  1609.         'lwp_wait': 167,
  1610.         'lwp_mutex_wakeup': 168,
  1611.         'lwp_mutex_lock': 169,
  1612.         'lwp_cond_wait': 170,
  1613.         'lwp_cond_signal': 171,
  1614.         'lwp_cond_broadcast': 172,
  1615.         'pread': 173,
  1616.         'pwrite': 174,
  1617.         'llseek': 175,
  1618.         'inst_sync': 176,
  1619.         'srmlimitsys': 177,
  1620.         'kaio': 178,
  1621.               #
  1622.               # subcodes:
  1623.               # aioread(...) :: kaio(AIOREAD, ...)
  1624.               # aiowrite(...) :: kaio(AIOWRITE, ...)
  1625.               # aiowait(...) :: kaio(AIOWAIT, ...)
  1626.               # aiocancel(...) :: kaio(AIOCANCEL, ...)
  1627.               # aionotify() :: kaio(AIONOTIFY)
  1628.               # aioinit() :: kaio(AIOINIT)
  1629.               # aiostart() :: kaio(AIOSTART)
  1630.               # see <sys/aio.h>
  1631.               # 
  1632.         'cpc': 179,
  1633.         'tsolsys': 184,
  1634.         'acl': 185,
  1635.         'auditsys': 186,
  1636.         'processor_bind': 187,
  1637.         'processor_info': 188,
  1638.         'p_online': 189,
  1639.         'sigqueue': 190,
  1640.         'clock_gettime': 191,
  1641.         'clock_settime': 192,
  1642.         'clock_getres': 193,
  1643.         'timer_create': 194,
  1644.         'timer_delete': 195,
  1645.         'timer_settime': 196,
  1646.         'timer_gettime': 197,
  1647.         'timer_getoverrun': 198,
  1648.         'nanosleep': 199,
  1649.         'facl': 200,
  1650.         'door': 201,
  1651.               #
  1652.               # Door Subcodes:
  1653.               # 0 door_create
  1654.               # 1 door_revoke
  1655.               # 2 door_info
  1656.               # 3 door_call
  1657.               # 4 door_return
  1658.               # 
  1659.         'setreuid': 202,
  1660.         'setregid': 203,
  1661.         'install_utrap': 204,
  1662.         'signotify': 205,
  1663.         'schedctl': 206,
  1664.         'pset': 207,
  1665.         'sparc_utrap_install': 208,
  1666.         'resolvepath': 209,
  1667.         'signotifywait': 210,
  1668.         'lwp_sigredirect': 211,
  1669.         'lwp_alarm': 212,
  1670.               # system calls for large file ( > 2 gigabyte) support
  1671.         'getdents64': 213,
  1672.         'mmap64': 214,
  1673.         'stat64': 215,
  1674.         'lstat64': 216,
  1675.         'fstat64': 217,
  1676.         'statvfs64': 218,
  1677.         'fstatvfs64': 219,
  1678.         'setrlimit64': 220,
  1679.         'getrlimit64': 221,
  1680.         'pread64': 222,
  1681.         'pwrite64': 223,
  1682.         'creat64': 224,
  1683.         'open64': 225,
  1684.         'rpcsys': 226,
  1685.         'socket': 230,
  1686.         'socketpair': 231,
  1687.         'bind': 232,
  1688.         'listen': 233,
  1689.         'accept': 234,
  1690.         'connect': 235,
  1691.         'shutdown': 236,
  1692.         'recv': 237,
  1693.         'recvfrom': 238,
  1694.         'recvmsg': 239,
  1695.         'send': 240,
  1696.         'sendmsg': 241,
  1697.         'sendto': 242,
  1698.         'getpeername': 243,
  1699.         'getsockname': 244,
  1700.         'getsockopt': 245,
  1701.         'setsockopt': 246,
  1702.         'sockconfig': 247,
  1703.               #
  1704.               # NTP codes
  1705.               #
  1706.         'ntp_gettime': 248,
  1707.         'ntp_adjtime': 249,
  1708.         'lwp_mutex_unlock': 250,
  1709.         'lwp_mutex_trylock': 251,
  1710.         'lwp_mutex_init': 252,
  1711.         'cladm': 253,
  1712.         'lwp_sigtimedwait': 254,
  1713.         'umount2': 255,
  1714.     }
  1715.  
  1716.     def syscall(self, number):
  1717.        answer = self.micro.push('eax')
  1718.        answer += self.micro.set('eax',number)+'\x9a\x00\x00\x00\x00\x07\x00' # callf 07:00000000
  1719.        self.micro.setValue('eax',None)
  1720.        return answer
  1721.  
  1722. class FreeBSDx86Syscall(OpenBSDx86Syscall):
  1723.     pass
  1724.  
  1725. class InlineEgg:
  1726.     # base
  1727.     
  1728.     def __init__(self,syscallClass = None, microClass = None):
  1729.         if not syscallClass:
  1730.             raise Exception, "You need to build an InlineEgg with the SyscallClass as argument"
  1731.         self.code = ''
  1732.         if not microClass:
  1733.            self.micro = syscallClass.microClass()
  1734.         else:
  1735.            self.micro = microClass()
  1736.         self.syscall  = syscallClass(self.micro)
  1737.         self.setBaseAddr(0)
  1738.         
  1739.     def setBaseAddr(self, addr):
  1740.         self.base_addr = addr
  1741.  
  1742.     def addCode(self,code):
  1743.         self.code += code
  1744.  
  1745.     def __str__(self):
  1746.         return self.getCode()
  1747.  
  1748.     def getCode(self):
  1749.         return self.code
  1750.  
  1751.     def __len__(self):
  1752.         return len(self.getCode())
  1753.  
  1754.     # system calls
  1755.     def _SysCall(self,name,args = ()):
  1756.         code,answer = self.syscall.call(name,args)
  1757.         self.addCode(code)
  1758.         return answer
  1759.  
  1760.     def setuid(self, uid):
  1761.         return self._SysCall('setuid',(uid,))
  1762.  
  1763.     def setgid(self, uid):
  1764.         return self._SysCall('setgid',(uid,))
  1765.  
  1766.     def exit(self, retVal = 0):
  1767.         return self._SysCall('exit',(retVal,))
  1768.  
  1769.     def fork(self):
  1770.         return self._SysCall('fork')
  1771.  
  1772.     def read(self,fd,buf,count):
  1773.         return self._SysCall('read',(fd,buf,count))
  1774.  
  1775.     def write(self,fd,buf,count):
  1776.         return self._SysCall('write',(fd,buf,count))
  1777.     
  1778.     def open(self,fileName,flags=0,mode=0):
  1779.         return self._SysCall('open',(fileName,flags,mode))
  1780.  
  1781.     def close(self,fd):
  1782.         return self._SysCall('close',(fd,))
  1783.  
  1784.     def execve(self,fileName,argv = 0,envp = 0):
  1785.         if self.micro.is_tuple(argv):
  1786.             argv = self.save(argv+(0,)).addr()
  1787.         if self.micro.is_tuple(envp):
  1788.             envp = self.save(envp+(0,)).addr()
  1789.         return self._SysCall('execve',(fileName,argv, envp))
  1790.  
  1791.     def ptrace(self,request,pid,addr = 0, data = 0):
  1792.         return self._SysCall('ptrace',(request,pid,addr,data))
  1793.  
  1794.     def mkdir(self, dir, mode = 0777):
  1795.         return self._SysCall('mkdir',(dir,mode))
  1796.  
  1797.     def chroot(self, dir):
  1798.         return self._SysCall('chroot',(dir,))
  1799.  
  1800.     def stat(self,fileName,statBuf):
  1801.         return self._SysCall('stat',(fileName,statBuf))
  1802.  
  1803.     def dup(self,fd):
  1804.         return self._SysCall('dup',(fd,))
  1805.  
  1806.     def dup2(self,fd1,fd2):
  1807.         return self._SysCall('dup2',(fd1,fd2))
  1808.  
  1809.     def fstat(self, fd, stat_buf):
  1810.         return self._SysCall('fstat',(fd, stat_buf))
  1811.  
  1812.     def signal(self,signal,action):
  1813.         return self._SysCall('signal',(signal,action))
  1814.  
  1815.     def kill(self, pid, signal):
  1816.         return self._SysCall('kill',(pid, signal))
  1817.  
  1818.     def sigaction(self,signal,action):
  1819.         print "Warning: this is not finished!"
  1820.         self.save(action)
  1821.         sigaction = self.micro.varAtTop().addr()
  1822.         self.alloc(4*4)
  1823.         self._SysCall('sigaction',(signal,sigaction,0,8))
  1824.         self.free(4*5)
  1825.  
  1826. # mmap gets arguments on stack
  1827. #    def mmap(self,start,length,prot,flags,fd,offset):
  1828. #        return self._SysCall('mmap',(start,length,prot,flags,fd,offset))
  1829.  
  1830.     def munmap(self,start,length):
  1831.         return self._SysCall('munmap',(start,length))
  1832.  
  1833.     def ioctl(self,fd,request,arg):
  1834.         return self._SysCall('ioctl',(fd,request,arg))
  1835.  
  1836.     # socket
  1837.     def socket(self, domain, type,proto = 0):
  1838.         return self._SysCall('socket',(domain,type,proto))
  1839.  
  1840.     def socketpair(self, domain, type, protocol,answer):
  1841.         return self._SysCall('socketpair',(domain,type,protocol,answer))
  1842.  
  1843.     def make_sockaddr(self, addr, family, len=16):
  1844.         ipaddr = self.inet_addr(addr[0])
  1845.         port   = struct.pack('!h',addr[1])
  1846.         family = struct.pack('<h',family)
  1847.         return '%s%s%s%s' % (family, port, ipaddr, '\x00'*(len-8))
  1848.  
  1849.     def inet_addr(self, ip):
  1850.         ipaddr = map(lambda x:int(x),ip.split('.'))
  1851.         ipaddr = apply(struct.pack,['BBBB']+ipaddr)
  1852.         return ipaddr
  1853.  
  1854.     def connect(self, sock, addr):
  1855.         # as socket.socket().connect(addr) addr is a pair: (ip_addr, port)
  1856.         sa = self.make_sockaddr(addr, 2)
  1857.         return self._SysCall('connect',(sock, sa, len(sa)))
  1858.     
  1859.     def bind(self, socket, addr):
  1860.         # as socket.socket().bind(addr) addr is a pair: (ip_addr, port)
  1861.         sa = self.make_sockaddr(addr, 2)
  1862.         return self._SysCall('bind',(socket, sa, len(sa)))
  1863.  
  1864.     def listen(self, sock, backlog):
  1865.         return self._SysCall('listen',(sock, backlog))
  1866.  
  1867.     def accept(self, sock, sa, salen):
  1868.         return self._SysCall('accept',(sock, sa, salen))
  1869.  
  1870.     def getpeername(self, socket, addr, lenp):
  1871.         answer = self._SysCall('getpeername',(socket,addr,lenp))
  1872.         return answer
  1873.  
  1874.     # language
  1875.  
  1876.     def save(self,value):
  1877.         save = self.micro.save(value)
  1878.         self.addCode(save[0])
  1879.         return save[1]
  1880.  
  1881.     def alloc(self,bytes):
  1882.         alloc = self.micro.alloc(bytes)
  1883.         self.addCode(alloc[0])
  1884.         return alloc[1]
  1885.  
  1886.     def free(self,bytes):
  1887.         self.addCode(self.micro.free(bytes))
  1888.  
  1889.     def freeStack(self):
  1890.         self.free(4*len(self.micro.stack))
  1891.  
  1892.     def pop(self,reg):
  1893.         self.addCode(self.micro.pop(reg))
  1894.  
  1895.     def While1(self):
  1896.         return While1InlineEgg(self)
  1897.  
  1898.     def While(self, left, condition, right):
  1899.         return WhileInlineEgg(self, left, condition, right)
  1900.  
  1901.     def Do(self):
  1902.         return DoInlineEgg(self)
  1903.  
  1904.     def Function(self):
  1905.         return FunctionInlineEgg(self)
  1906.  
  1907.     def call(self,function):
  1908.         if type(function) == types.IntType:
  1909.             code = self.micro.call(int(function)-len(self.code)-self.base_addr)
  1910.         else:
  1911.             code = self.micro.call(int(function.address[5:])-len(self.code))
  1912.         self.addCode(code)
  1913.  
  1914.     def label(self, delta = 0):
  1915.         return 'label%d' % (len(self.code)+delta)
  1916.  
  1917.     def jump(self,label,condition = ''):
  1918.         if type(label) == types.IntType:
  1919.             code = self.micro.jumpRel(int(label)-len(self.code)-self.base_addr)
  1920.         else:
  1921.             code = self.micro.jumpRel(int(label[5:])-len(self.code),condition)
  1922.         self.addCode(code)
  1923.  
  1924.     def If(self, left, condition, right):
  1925.         return IfInlineEgg(self, left, condition, right)
  1926.  
  1927.     def ret(self, n = 0):
  1928.         self.addCode(self.micro.ret(n))
  1929.  
  1930.     # utils
  1931.  
  1932.     def dumpBin(self, fileName):
  1933.         open(fileName,'w').write(self.getCode())
  1934.  
  1935.     def dumpS(self,fileName):
  1936.         f = open(fileName,'w')
  1937.         f.write("""
  1938.     .text
  1939.     .align  4
  1940.     .globl  _start
  1941.     .type   _start,@function
  1942.  
  1943. _start:
  1944.     .byte   """)
  1945.         bytes = struct.unpack('%db' % len(self.code), self.code)
  1946.         bytes = map(lambda x: '0x%02x' % (x & 0xff),bytes)
  1947.         bytes = ','.join(bytes)
  1948.         f.write(bytes+'\n')
  1949.         f.close()
  1950.  
  1951.     def dumpElf(self,fileName, base = 0x8048000):
  1952.         import exelib
  1953.         import os
  1954.  
  1955.         ei_osabi_mapping = {
  1956.            Linuxx86Syscall:     exelib.ELFOSABI_SYSV,
  1957.            FreeBSDx86Syscall:   exelib.ELFOSABI_FREEBSD,
  1958.            OpenBSDx86Syscall:   exelib.ELFOSABI_OPENBSD,
  1959.            Solarisx86Syscall:   exelib.ELFOSABI_SYSV,
  1960.         }
  1961.         elf = exelib.Elf32Program(ei_osabi_mapping[self.syscall.__class__])
  1962.         elf.setArch(elf.ARCH_I386)
  1963.         elf.addCode(self.code)
  1964.  
  1965.         p = elf.programTable[0]
  1966.         p.p_vaddr = base
  1967.         elf.header.e_entry = p.p_vaddr+elf.totalHeaderLength()
  1968.  
  1969.         f = open(fileName,'w')
  1970.         f.write(elf.bytes())
  1971.         f.close()
  1972.         os.chmod(fileName,0755)
  1973.  
  1974.     def dumpAOut(self,fileName):
  1975.         import exelib
  1976.         import os
  1977.         elf = exelib.AOutProgram()
  1978.         elf.setArch(elf.ARCH_I386)
  1979.         elf.addCode(self.code)
  1980.  
  1981.         f = open(fileName,'w')
  1982.         f.write(elf.bytes())
  1983.         f.close()
  1984.         os.chmod(fileName,0755)
  1985.  
  1986.     def dumpExe(self, fileName):
  1987.         import exelib
  1988.         exe = exelib.PEProgram()
  1989.         exe.addCode(self.code)
  1990.         f = open(fileName, "w")
  1991.         f.write(exe.bytes())
  1992.         f.close()
  1993.  
  1994.  
  1995. # XXX: This classes still have problems saving/restoring/tracking registers
  1996. #      for example, If will not be careful enough with registers, and may
  1997. #      wronly assume a register is set to some value, after exiting the If
  1998.  
  1999. class LanguageInlineEgg(InlineEgg):
  2000.     def __init__(self,outer):
  2001.         InlineEgg.__init__(self,outer.syscall.__class__,outer.micro.__class__)
  2002.         self.outer = outer
  2003.         self.original_stack_size = 0
  2004.         self.setBaseAddr(self.outer.base_addr+len(self.outer))
  2005.  
  2006.     def freeStack(self):
  2007.         self.free(4*(len(self.micro.stack)-self.original_stack_size))
  2008.  
  2009.     # private
  2010.     def stackFromOuter(self):
  2011.         # we need to copy the stack so variables declared outside the statement
  2012.         # can be accessed inside it
  2013.         self.micro.stack = self.outer.micro.stack
  2014.         self.original_stack_size = len(self.micro.stack)
  2015.  
  2016.     def codeFromOuter(self):
  2017.         # the initial size of code must match that of outer
  2018.         # so jumps and labels are coherent inside and outside
  2019.         self.code = '.'*len(self.outer.code)
  2020.  
  2021.  
  2022. class While1InlineEgg(LanguageInlineEgg):
  2023.     def __init__(self,outer):
  2024.         LanguageInlineEgg.__init__(self,outer)
  2025.         self.stackFromOuter()
  2026.  
  2027.     def end(self):
  2028.         loop = self.outer.label()
  2029.         self.freeStack()
  2030.         self.outer.addCode(self.code)
  2031.         self.outer.jump(loop)
  2032.  
  2033.  
  2034. class FunctionInlineEgg(LanguageInlineEgg):
  2035.     def __init__(self,outer):
  2036.         LanguageInlineEgg.__init__(self,outer)
  2037.  
  2038.         # only for recursion, and only possible this easy if
  2039.         # calls and jumps are relative
  2040.         self.address = self.label()
  2041.  
  2042.     def end(self):
  2043.         self.freeStack()
  2044.         self.ret()
  2045.  
  2046.         real_size = len(self)
  2047.         self.jump(self.address)
  2048.         self.outer.jump(self.outer.label(len(self)))
  2049.         self.address = self.outer.label()
  2050.         self.outer.addCode(self.getCode()[:real_size])
  2051.  
  2052. class IfInlineEgg(LanguageInlineEgg):
  2053.     def __init__(self,outer, left, condition, right):
  2054.         LanguageInlineEgg.__init__(self,outer)
  2055.         self.condition = condition
  2056.         if left:
  2057.             outer.addCode(outer.micro.cmp(left, right))
  2058.         self.top_label = self.label()
  2059.         self.stackFromOuter()
  2060.  
  2061.     def end(self):
  2062.         self.freeStack()
  2063.  
  2064.         real_size = len(self)
  2065.         self.jump(self.top_label,self.micro.opositeCondition(self.condition))
  2066.         self.outer.jump(self.outer.label(len(self)),self.micro.opositeCondition(self.condition))
  2067.         self.outer.addCode(self.getCode()[:real_size])
  2068.  
  2069. class WhileInlineEgg(LanguageInlineEgg):
  2070.     def __init__(self,outer, left, condition, right):
  2071.         LanguageInlineEgg.__init__(self,outer)
  2072.         self.condition = condition
  2073.  
  2074.         self.top_label = self.label()
  2075.         self.loop = self.outer.label()
  2076.         self.outer.addCode(outer.micro.cmp(left, right))
  2077.         self.stackFromOuter()
  2078.  
  2079.     def end(self):
  2080.         self.freeStack()
  2081.  
  2082.         real_size = len(self)
  2083.         self.jump(self.top_label,self.micro.opositeCondition(self.condition))
  2084.         self.jump(self.top_label)
  2085.         self.outer.jump(self.outer.label(len(self)),self.micro.opositeCondition(self.condition))
  2086.         self.outer.addCode(self.getCode()[:real_size])
  2087.         self.outer.jump(self.loop)
  2088.  
  2089. class DoInlineEgg(LanguageInlineEgg):
  2090.     def __init__(self,outer):
  2091.         LanguageInlineEgg.__init__(self,outer)
  2092.  
  2093.         self.loop = self.outer.label()
  2094.         self.stackFromOuter()
  2095.  
  2096.     def While(self, left, condition, right):
  2097.         self.freeStack()
  2098.         self.outer.addCode(self.code)
  2099.         self.outer.addCode(self.micro.cmp(left, right))
  2100.         self.outer.jump(self.loop,condition)
  2101.